package fr.lip6.move.care

import sdmakerz_v1.coresyntax.generator.SDMakerV1IDProvider
import sdmakerz_v1.coresyntax.generator.interfaces.IContext
import sdmakerz_v1.coresyntax.sDMakerV1.Opt
import sdmakerz_v1.coresyntax.generator.interfaces.IConfigData

class CareOptGen {
	private CareGen mainGenerator;
	
	new(CareGen mainGenerator){
		this.mainGenerator= mainGenerator;
	}
	
	def public
	CompileResult compile(IContext context, Opt opt){
		    
    var IConfigData config= context.getConfigData   
    var java.util.ArrayList<CompileResult> nestedResults= 
    	new java.util.ArrayList<CompileResult>();
    var java.util.ArrayList<String> nestedEltIDs= 
    	new java.util.ArrayList<String>();
    var CompileResult compRes
    var optID= "opt_id"+SDMakerV1IDProvider::computeID
    var double probExec= -1;
    
    
    if(opt.probExec != null &&
       0 < opt.probExec.value && opt.probExec.value <= 1 ){
        probExec= opt.probExec.value;
    }
    else{
        probExec= config.probExecOpt;
    }

    var CharSequence charSequenceResult=
    '''
    
    «FOR elt: opt.opts»
    «SDMakerToCareUtils::toNullExp(compRes= mainGenerator.compile(context, elt))»
    «SDMakerToCareUtils::toNullExp(nestedResults.add(compRes))»
    «SDMakerToCareUtils::toNullExp(nestedEltIDs.add(compRes.eltID))»
    «ENDFOR»
    
    «IF nestedEltIDs.size == 1»
    /* OPT: «optID» */
     «nestedResults.get(0).charSequenceResult»
    «IF 0 < probExec && probExec <= 1»
    Opt «optID» = new Opt(«nestedEltIDs.get(0)», «probExec»);
    «ELSE»
    Opt «optID» = new Opt(«nestedEltIDs.get(0)»);
    «ENDIF»
    «ELSEIF nestedEltIDs.size > 1»
    /* OPT: «optID» */
    BlockList bloc_«optID» = new BlockList();
    «FOR nestedResult: nestedResults»
    «nestedResult.charSequenceResult»
    «ENDFOR»
    
    //add(s) for bloc_«optID»
    «FOR eltID: nestedEltIDs»
    bloc_«optID».add(«eltID»);
    «ENDFOR»
    
    /* FINALIZING «optID» */
    «IF 0 < probExec && probExec <= 1»
    Opt «optID» = new Opt(bloc_«optID», «probExec»);
    «ELSE»
    Opt «optID» = new Opt(bloc_«optID»);
    «ENDIF»
    «ENDIF»
    '''
    
    
    return new CompileResult(
    				charSequenceResult,
    				optID,
    				true)
	}
}